#include "client_manager.h"
#include <QHostAddress>
#include "message.h"
ClientManager * ClientManager::m_instance = nullptr;
QMutex ClientManager::m_mutex;

ClientManager & ClientManager::getInstance()
{
    if(nullptr == m_instance){
        QMutexLocker lock(&m_mutex);
        if(nullptr == m_instance){
            m_instance = new ClientManager();
        }
    }

    return * m_instance;
}

void  ClientManager::addClient(const QHostAddress &ip, quint16 port)
{
    QString key = QString("%1:%2")
              .arg(ip.toString()).arg(port);
    if(m_clientList.contains(key)){
        return ;
    }

    NodeItem *node = new NodeItem();
    node->addr = ip;
    node->port = port;
    node->count = 10;//设置生命期为10
    m_clientList[key] = node;
}

int ClientManager::heart(const QHostAddress &ip, quint16 port)
{
    QString key = QString("%1:%2")
                      .arg(ip.toString()).arg(port);
    if(!m_clientList.contains(key)){
        addClient(ip,port);
    }

    m_clientList[key]->count = 10;
    return m_clientList[key]->count;
}

void ClientManager::timeout()
{
    auto it = m_clientList.constBegin();
    QList<QString>  removeList ;
    for(;it != m_clientList.constEnd(); ++it){
        NodeItem *node = it.value();
        node->count--;
        if(node->count <= 0){
            removeList.append(it.key());
        }
    }

    foreach (QString key, removeList) {
        NodeItem *node = m_clientList[key];
        m_clientList.remove(key);
        delete node;
    }


}

void ClientManager::sendData(QUdpSocket &udp, const QString &data)
{
    Message message(data);

    auto it = m_clientList.constBegin();

    for(;it != m_clientList.constEnd(); ++it){
        NodeItem *node = it.value();
        //发送数据，需要指定接收方的IP与端口
        udp.writeDatagram(message.toByteArray(),  node->addr, node->port);
    }

}

int ClientManager::clientCount()
{
    return m_clientList.size();
}

void ClientManager::closeAllClients()
{
    //清空客户端列表
    auto it = m_clientList.constBegin();

    for(;it != m_clientList.constEnd(); ++it){
        NodeItem *node = it.value();
        delete node;
    }
    m_clientList.clear();
}
